import {Component, ComponentFactoryResolver, Input, OnChanges, OnInit, SimpleChange, SimpleChanges, Type, ViewContainerRef} from '@angular/core';
import {DynamicComponentEvent, DynamicComponent} from './dynamic-component.interface';


/**
 * 动态生成组件
 * */
@Component({
  selector: 'ng-tools-dynamic-component',
  templateUrl: './dynamic-component.component.html',
  styleUrls: ['./dynamic-component.component.scss']
})
export class DynamicComponentComponent implements OnInit, OnChanges {
  @Input() component: Type<Component>;
  @Input() data: any;
  @Input() events: DynamicComponentEvent;
  @Input() context: any; // 上下文关系
  private instance;

  constructor(private viewContainer: ViewContainerRef,
              private componentFactoryResolver: ComponentFactoryResolver) {
  }

  createComponent() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.component);
    this.viewContainer.clear();
    const componentRef = this.viewContainer.createComponent(componentFactory, 0);
    return <DynamicComponent>componentRef.instance;
  }

  ngOnInit() {
  }


  applyChanges(firstChange: boolean) {
    this.instance.data = this.data;
    this.instance.events = this.events;
    this.instance.context = this.context;
    const changes = {
      data: new SimpleChange(null, this.data, firstChange)
    };
    if ('ngOnChanges' in this.instance) {
      this.instance['ngOnChanges'](changes);
    }
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.component) {
      this.instance = this.createComponent();
    }
    if (changes.data && changes.component) {
      this.applyChanges(changes.data.firstChange || changes.component.firstChange);
    }
  }

}
